﻿using SimpleBoard.Behavior;
using SimpleBoard.ControllerMeta;
using SimpleBoard.DependencyInjection;
using SimpleBoard.Project.Binding;
using SimpleBoard.Project.Data;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Windows;

namespace SimpleBoard.Designer.Services
{
    [InjectAs(InjectionType.Singleton)]
    public class ControllerService
    {
        public List<ControllerInfo> Controllers { get; private set; } = new();

        /// <summary>
        /// 从程序集加载控件
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public bool LoadControllerAssembly(string filePath)
        {
            var assembly = Assembly.LoadFrom(filePath);
            if (assembly == null) return false;

            var controllers = from type in assembly.GetTypes()
                              where !type.IsGenericType
                              where type.IsSubclassOf(typeof(FrameworkElement))
                              where type.GetCustomAttribute<SimpleBoardControllerAttribute>() is not null
                              let info = type.GetCustomAttribute<SimpleBoardControllerAttribute>()
                              let properties = type.GetCustomAttributes<HasConfigurablePropertyAttribute>()
                              select new ControllerInfo
                              {
                                  Title = info.Title,
                                  TypeFullName = type.FullName!,
                                  AssemblyFullName = assembly.FullName!,
                                  Properties = properties.Select(x => new ControllerMeta.PropertyInfo
                                  {
                                      Name = x.PropertyName,
                                      Type = x.PropertyType,
                                      Title = x.Title,
                                  }).ToList()
                              };
            this.Controllers.AddRange(controllers);
            return true;
        }
        
        /// <summary>
        /// 从Behavior中获取尺寸
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public Size GetSize(FrameworkElement element)
        {
            var behavior = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(element)
                    .Where(x => x.GetType() == typeof(TranslateZoomBehavior))
                    .Cast<TranslateZoomBehavior>()
                    .Single();
            return behavior.Size;
        }

        /// <summary>
        /// 从Behavior中获取位置
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public Point GetPosition(FrameworkElement element)
        {
            var behavior = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(element)
                    .Where(x => x.GetType() == typeof(TranslateZoomBehavior))
                    .Cast<TranslateZoomBehavior>()
                    .Single();
            return behavior.Position;
        }

        /// <summary>
        /// 通过Behavior设置宽度
        /// </summary>
        /// <param name="element"></param>
        /// <param name="width"></param>
        public void SetWidth(FrameworkElement element, int width)
        {
            var behavior = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(element)
                    .Where(x => x.GetType() == typeof(TranslateZoomBehavior))
                    .Cast<TranslateZoomBehavior>()
                    .Single();
            behavior.Size = new Size(width, behavior.Size.Height);
        }

        /// <summary>
        /// 通过Behavior设置高度
        /// </summary>
        /// <param name="element"></param>
        /// <param name="height"></param>
        public void SetHeight(FrameworkElement element, int height)
        {
            var behavior = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(element)
                    .Where(x => x.GetType() == typeof(TranslateZoomBehavior))
                    .Cast<TranslateZoomBehavior>()
                    .Single();
            behavior.Size = new Size(behavior.Size.Width, height);
        }

        /// <summary>
        /// 通过Behavior设置X
        /// </summary>
        /// <param name="element"></param>
        /// <param name="left"></param>
        public void SetLeft(FrameworkElement element, int left)
        {
            var behavior = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(element)
                    .Where(x => x.GetType() == typeof(TranslateZoomBehavior))
                    .Cast<TranslateZoomBehavior>()
                    .Single();
            behavior.Position = new Point(left, behavior.Position.Y);
        }

        /// <summary>
        /// 通过Behavior设置Y
        /// </summary>
        /// <param name="element"></param>
        /// <param name="top"></param>
        public void SetTop(FrameworkElement element, int top)
        {
            var behavior = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(element)
                    .Where(x => x.GetType() == typeof(TranslateZoomBehavior))
                    .Cast<TranslateZoomBehavior>()
                    .Single();
            behavior.Position = new Point(behavior.Position.X, top);
        }

        /// <summary>
        /// 获取控件信息
        /// </summary>
        /// <param name="element"></param>
        /// <returns></returns>
        public ControllerInfo GetControllerInfo(FrameworkElement element)
        {
            return Controllers.Where(x => x.TypeFullName == element.GetType().FullName).Single();
        }
    }
}
